// 核心原则
// 尽量避免在C++中使用转型（casting），特别是旧式的C风格转型。如果必须使用转型，优先选择新式的C++风格转型，并将它们集中和隐藏在代码中。

// 为什么转型是危险的
// 在C++中，转型操作看似简单，但实际上可能导致多种问题：
// 1.破坏类型系统：转型可以绕过C++的类型检查机制
// 2.可能导致未定义行为：某些转型操作可能产生不可预测的结果
// 3.掩盖设计问题：过度使用转型通常表明设计存在缺陷
// 4.降低代码可读性和可维护性：转型使代码更难理解和维护
// 5.运行时开销：某些转型（特别是dynamic_cast）可能带来性能损失

// C++中的转型类型
// 旧式（C风格）转型
// C风格转型
double d = 3.14159;
int i = (int)d; // C风格转型

// 函数风格转型
int j = int(d); // 函数风格转型
// 这些旧式转型难以在代码中识别，且能执行多种不同类型的转换，包括一些危险的操作。

// 新式（C++风格）转型
// C++引入了四种更安全、更明确的转型操作符：
// static_cast<T>()：用于"合理的"类型转换
// dynamic_cast<T>()：用于多态类层次结构中的安全向下转型
// const_cast<T>()：用于添加或移除const限定符
// reinterpret_cast<T>()：用于低级别的、不可移植的类型转换

// 详细解析各种转型
// 1. static_cast
// static_cast用于编译时可检查的类型转换，如：
// 1)基本数据类型之间的转换
// 2)子类指针到基类指针的向上转型
// 3)显式调用转换构造函数或转换操作符
double d = 3.14159;
int i = static_cast<int>(d); // 浮点数到整数

class Base
{
};
class Derived : public Base
{
};
Derived *pd = new Derived;
Base *pb = static_cast<Base *>(pd); // 向上转型，安全

// 2. dynamic_cast
// dynamic_cast主要用于多态类层次结构中的安全向下转型，它会在运行时检查转型是否有效：
class Base
{
public:
    virtual ~Base() {} // 必须有虚函数才能使用dynamic_cast
};

class Derived : public Base
{
public:
    void derivedFunction() {}
};

void processObject(Base *bp)
{
    // 安全地检查bp是否指向Derived对象
    Derived *dp = dynamic_cast<Derived *>(bp);
    if (dp)
    { // 转型成功
        dp->derivedFunction();
    }
    else
    { // 转型失败
      // 处理非Derived对象
    }
}
// 如果转型失败：
// 对于指针，返回空指针
// 对于引用，抛出std::bad_cast异常

// 3. const_cast
// const_cast是唯一能够移除const或volatile限定符的C++转型操作符：void updateValue(char* str) {
// 函数需要非const参数

void processString(const char *str)
{
    // 移除const限定符（谨慎使用！）
    updateValue(const_cast<char *>(str));
}
// 警告：如果原始对象确实是const的，通过const_cast修改它会导致未定义行为。

// 4. reinterpret_cast
// reinterpret_cast执行低级别的、不可移植的转换，如指针到整数或不同类型指针之间的转换：
int *p = new int(42);
// 将指针转换为整数
uintptr_t address = reinterpret_cast<uintptr_t>(p);
// 将整数转回指针
int *p2 = reinterpret_cast<int *>(address);

// 警告：这是最危险的转型，应该极少使用，通常只在系统级编程中需要。
// 转型的常见问题与解决方案
// 问题1：多重继承中的指针转换
// 在多重继承中，指针值可能会在转型过程中发生调整：
class Base1
{ /* ... */
};
class Base2
{ /* ... */
};
class Derived : public Base1, public Base2
{ /* ... */
};

Derived *pd = new Derived;
Base2 *pb2 = pd;                            // 隐式转换，可能调整指针值
Derived *pd2 = static_cast<Derived *>(pb2); // 转回Derived*，也会调整指针值
// 这些指针调整是由编译器自动处理的，但它们会带来运行时开销。
